﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Threading;
using System.Windows.Markup;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Reflection;
using System.Windows.Controls;

namespace Invini.Training
{
    public class RestrictPasswordAction : TrainingActionBase
    {
        private class ActivePassword
        {
            private PasswordBox passwordBox;
            private string currentPassword;
            private string expectedPassword;

            public ActivePassword(PasswordBox passwordBox, string expectedPassword)
            {
                this.passwordBox = passwordBox;
                this.passwordBox.PasswordChanged += this.passwordChanged;
                this.expectedPassword = expectedPassword;
            }
            public void Clear()
            {
                this.currentPassword = passwordBox.Password;
                this.passwordBox.PasswordChanged -= this.passwordChanged;
            }

            private void passwordChanged(object sender, RoutedEventArgs e)
            {
                if (passwordBox.Password == null || this.expectedPassword == null)
                    return;

                if (!this.expectedPassword.StartsWith(passwordBox.Password))
                {
                    passwordBox.Password = this.currentPassword;
                    return;
                }

                this.currentPassword = passwordBox.Password;
            }
        }

        public PathComponentsCollection Element
        {
            get;
            set;
        }
        public string Password
        {
            get;
            set;
        }

        private List<ActivePassword> activePasswords;

        public RestrictPasswordAction()
        {
            this.Element = new PathComponentsCollection();
        }
        public override void Execute()
        {
            if (this.Element == null)
            {
                this.onCompleted();
                return;
            }

            IEnumerable<object> objects = this.Element.FindElements();
            if (objects.Count() == 0)
            {
                this.onCompleted();
                return;
            }

            this.activePasswords = new List<ActivePassword>();

            foreach (DependencyObject dpo in objects)
            {
                PasswordBox passwordBox = dpo as PasswordBox;
                if (passwordBox == null)
                    continue;

                this.activePasswords.Add(new ActivePassword(passwordBox, this.Password));
            }

            this.onCompleted();
        }
        public override void Clear()
        {
            base.Clear();

            if (this.activePasswords != null)
            {
                foreach (ActivePassword activePassword in this.activePasswords)
                    activePassword.Clear();

                this.activePasswords = null;
            }
        }
    }
}
